BigQuery DataFramesを使ってみる
はじめに
データアナリティクス事業本部のkobayashiです。
BigQueryのエンジンを利用してPandas互換のDataframeやscikit-learnライクな機械学習ライブラリを扱えるBigQuery DataFramesを使ってみたのでまとめます。
BigQuery DataFramesとは
BigQuery DataFramesは、DataFrameとしてはpandas互換のPythonic DataFrameのbigframes.pandas
モジュールとscikit-learnライクのbigframes.ml
モジュールを扱うことができ、それらの機能をBigQueryエンジンで実行することができます。
詳しくは以下をご確認ください。
BigQuery DataFramesを使ってみる
では早速BigQuery DataFramesを使ってみたいと思います。試すこととしてはまずはpandas互換のPythonic DataFrameのbigframes.pandas
モジュールで一般的にPandasで行うデータ分析を行ってみます。
scikit-learnライクのbigframes.ml
モジュールに関しては別エントリでまとめたいと思います。
環境
- Python: 3.11.4
- bigframes: 0.3.0
インストール
インストールはいつも通りpipで簡単に済ませます。
$ pip install bigframes
BigQuery DataFramesを使ってみる
BigQuery DataFramesの準備が整ったので早速試してみたいと思います。
扱うデータは以下のような天候データを扱います。
SELECT * FROM {project_id}.data_set_test.jp_weather;
date | month | city | w_type | temperature | precipitation | sunlight | cloudage |
---|---|---|---|---|---|---|---|
2021-11-13 | 11 | 京都 | 晴 | 10.500000000 | 0.000000000 | 7.600000000 | null |
2021-03-03 | 3 | 京都 | 晴 | 5.900000000 | 0.000000000 | 6.600000000 | null |
2021-11-14 | 11 | 京都 | 晴 | 12.100000000 | 0.000000000 | 3.600000000 | null |
2021-03-04 | 3 | 京都 | 晴 | 10.000000000 | 0.000000000 | 6.100000000 | null |
2021-11-15 | 11 | 京都 | 晴 | 12.800000000 | 0.000000000 | 7.900000000 | null |
2021-11-16 | 11 | 京都 | 晴 | 13.500000000 | 0.000000000 | 7.600000000 | null |
2021-11-17 | 11 | 京都 | 晴 | 12.800000000 | 0.000000000 | 8.000000000 | null |
2021-03-07 | 3 | 京都 | 晴 | 8.200000000 | 0.000000000 | 6.100000000 | null |
このデータをBigQuery DataFramesで扱います。内容としては{project_id}.data_set_test.jp_weather
のデータを使ってPandasで行う一般的な分析操作を行います。コードは以下になります。
import os import bigframes.pandas as bpd bpd.options.bigquery.project = os.environ.get("GOOGLE_PROJECT_ID") bpd.options.bigquery.location = "asia-northeast1" df1 = bpd.read_gbq("{project_id}.data_set_test.jp_weather") # df1 = bpd.read_gbq("SELECT * FROM {project_id}.data_set_test.jp_weather") # データの要約 ## 最初の5行を取得 print(df1.head()) ## 最後の5行を取得 print(df1.tail()) ## 行数・列数を取得 print(df1.shape) ## 列名の取得 print(df1.columns) ## 列のデータ型を取得 print(df1.dtypes) ## 要約統計量 print(df1.describe()) # データの加工 ## 列の抽出 print(df1["date"]) print(df1[["date", "temperature"]]) ## cityごとのデータ数 print(df1["city"].value_counts()) # データの集計 print(df1.groupby("city")["temperature"].mean().sort_values(ascending=False))
使い方として主な箇所は1行目から7行目になります。
- 2行目:
import bigframes.pandas as bpd
でbigframes.pandas
モジュールをインポートする - 4行目:
bpd.options.bigquery.project
にGoogleCloudのプロジェクトIDを設定する - 5行目:
bpd.options.bigquery.location
でデータセットのロケーションを設定する。設定しない場合はデフォルトのUS
ロケーションが使われる。 - 7行目:
bpd.read_gbq()
でデータを読み込む。引数には上記のコードの様にテーブルIDを指定する方法とSQLを指定する方法が可能。
9行明以降はPandasで扱える処理をbigframes.pandas
モジュールでも使ってみます。結果は以下のように通常のpandasと同様の結果が返ってきますのでPandasでのデータ分析を普段から行っているなら特に違和感なく使えるかと思います。
# データの要約 ## 最初の5行を取得 date month city ... precipitation sunlight cloudage 0 2021-11-13 11 京都 ... 0E-9 7.600000000 None 1 2021-03-03 3 京都 ... 0E-9 6.600000000 None 2 2021-11-14 11 京都 ... 0E-9 3.600000000 None 3 2021-03-04 3 京都 ... 0E-9 6.100000000 None 4 2021-11-15 11 京都 ... 0E-9 7.900000000 None [5 rows x 8 columns] ## 最後の5行を取得 date month city ... precipitation sunlight cloudage 3655 2021-04-14 4 名古屋 ... 2.500000000 6.000000000 5.800000000 3656 2021-04-22 4 名古屋 ... 0E-9 11.500000000 5.800000000 3657 2022-01-16 1 名古屋 ... 0E-9 9.000000000 5.800000000 3658 2021-07-30 7 名古屋 ... 2.000000000 8.200000000 5.800000000 3659 2021-11-10 11 名古屋 ... 0E-9 4.200000000 5.800000000 [5 rows x 8 columns] ## 行数・列数を取得 (3660, 8) ## 列名の取得 Index(['date', 'month', 'city', 'w_type', 'temperature', 'precipitation', 'sunlight', 'cloudage'], dtype='object') ## 列のデータ型を取得 date date32[day][pyarrow] month Int64 city string[pyarrow] w_type string[pyarrow] temperature object precipitation object sunlight object cloudage object dtype: object ## 要約統計量 date month count 3660 3660.0 mean 2021-08-21 12:00:00 6.513661 min 2021-02-20 00:00:00 1.0 25% 2021-05-22 00:00:00 4.0 50% 2021-08-21 12:00:00 7.0 75% 2021-11-21 00:00:00 10.0 max 2022-02-20 00:00:00 12.0 std NaN 3.451705 ## 列の抽出 0 2021-11-13 1 2021-03-03 2 2021-11-14 3 2021-03-04 4 2021-11-15 ... 3655 2021-04-14 3656 2021-04-22 3657 2022-01-16 3658 2021-07-30 3659 2021-11-10 Name: date, Length: 3660, dtype: datetime64[s] ## 列の抽出 date temperature 0 2021-11-13 10.500000000 1 2021-03-03 5.900000000 2 2021-11-14 12.100000000 3 2021-03-04 10.000000000 4 2021-11-15 12.800000000 ... ... ... 3655 2021-04-14 16.100000000 3656 2021-04-22 19.900000000 3657 2022-01-16 4.300000000 3658 2021-07-30 29.100000000 3659 2021-11-10 13.300000000 [3660 rows x 2 columns] ## cityごとのデータ数 city 京都 366 仙台 366 大阪 366 札幌 366 東京 366 横浜 366 福岡 366 那覇 366 長野 366 名古屋 366 Name: count, dtype: int64[pyarrow] date month city ... precipitation sunlight cloudage 0 2021-11-13 11 京都 ... 0E-9 7.600000000 None 1 2021-03-03 3 京都 ... 0E-9 6.600000000 None 2 2021-11-14 11 京都 ... 0E-9 3.600000000 None 3 2021-03-04 3 京都 ... 0E-9 6.100000000 None 4 2021-11-15 11 京都 ... 0E-9 7.900000000 None ... ... ... ... ... ... ... ... 3655 2021-04-14 4 名古屋 ... 2.500000000 6.000000000 5.800000000 3656 2021-04-22 4 名古屋 ... 0E-9 11.500000000 5.800000000 3657 2022-01-16 1 名古屋 ... 0E-9 9.000000000 5.800000000 3658 2021-07-30 7 名古屋 ... 2.000000000 8.200000000 5.800000000 3659 2021-11-10 11 名古屋 ... 0E-9 4.200000000 5.800000000 [3660 rows x 8 columns] # データの集計 city 那覇 23.688798 福岡 18.062022 大阪 17.378142 横浜 16.779235 京都 16.674044 名古屋 16.671038 東京 16.418579 仙台 13.662295 長野 12.698361 札幌 10.26694 Name: temperature, dtype: object
データのメモリ展開
上記のコードですが、BigQuery DataFramesの特性上、BigQuery サービス上でデータと処理を保持をされています。したがってdf1
を使って操作を行うたびにBigQueryのセッションからデータを取得しています。代わりに
df1 = bpd.read_gbq("{project_id}.data_set_test.jp_weather").to_pandas()
のようにするとこの時点でデータをメモリ上に読み込んでから後続の処理をするようになります。この場合はdf1
の操作のたびにBigQueryのAPIを呼び出すことはしなくなしますが、実行マシーンのメモリを圧迫するのでケースバイケースでの使い分けが必要になります。
まとめ
BigQueryのエンジンを利用してPandas互換のDataframeを扱えるBigQuery DataFramesを使ってみました。bigframes.pandas.read_gbq()
でBigQuery上のデータを読み込んでしまえば以降はPandasと同じ関数を使って分析を行うことができ非常に便利です。
次回、scikit-learnライクのbigframes.ml
モジュールを扱ってみたいと思います。
最後まで読んで頂いてありがとうございました。